﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace PPSkin
{
    [Description("圆角textbox，可自定义粗细及颜色")]
    public partial class PPNumericUpDown : PPControlBase
    {
        #region 私有属性

        private int maxinum = 100;

        private int mininum = 0;

        private int value = 0;

        private int padleftCount = 0;

        private Size buttonSize = new Size(13, 13);

        #endregion 私有属性

        /// <summary>
        /// 字符串颜色
        /// </summary>
        [Description("字符串颜色")]
        public override Color ForeColor
        {
            get
            {
                return textBox1.ForeColor;
            }

            set
            {
                base.ForeColor = value;
                textBox1.ForeColor = base.ForeColor;
            }
        }

        [Description("显示位数"), Category("PPSkin.NumericUpDown")]
        public int PadLeftCount
        {
            get { return padleftCount; }
            set
            {
                if (value >= 0)
                    padleftCount = value;
            }
        }

        [Description("值"), Category("PPSkin.NumericUpDown")]
        public int Value
        {
            get { return value; }
            set
            {
                if (value <= maxinum && value >= mininum)
                {
                    this.value = value;
                    if (padleftCount > 0)
                    {
                        textBox1.Text = this.value.ToString().PadLeft(padleftCount, '0');
                    }
                    else
                    {
                        textBox1.Text = this.value.ToString();
                    }
                }
            }
        }

        [Description("最大值"), Category("PPSkin.NumericUpDown")]
        public int Maxinum
        {
            get { return maxinum; }
            set
            {
                maxinum = value;
                if (maxinum < mininum)
                {
                    mininum = maxinum;
                }
            }
        }

        [Description("最小值"), Category("PPSkin.NumericUpDown")]
        public int Mininum
        {
            get { return mininum; }
            set
            {
                mininum = value;
                if (mininum > maxinum)
                {
                    maxinum = mininum;
                }
            }
        }

        [Description("按钮大小"), Category("PPSkin.NumericUpDown")]
        public Size ButtonSize
        {
            get { return buttonSize; }
            set
            {
                if (value.Width > 0 && value.Width < this.Width - Radius - 4 && value.Height < this.Height / 2)
                {
                    buttonSize = value;
                    pictureBox1.Size = pictureBox2.Size = value;
                    pictureBox1.Location = new Point(base.Width - buttonSize.Width - Radius / 2, 0 + (this.Height / 2 - buttonSize.Height) / 2);
                    pictureBox2.Location = new Point(base.Width - buttonSize.Width - Radius / 2, this.Height / 2 + (this.Height / 2 - buttonSize.Height) / 2);
                }
            }
        }

        private Bitmap buttonPicUp = PPSkinResources.up.Clone() as Bitmap;
        private Bitmap buttonPicUpHover = PPSkinResources.upBlue.Clone() as Bitmap;
        private Bitmap buttonPicDown = PPSkinResources.down.Clone() as Bitmap;
        private Bitmap buttonPicDownHover = PPSkinResources.downBlue.Clone() as Bitmap;

        [Description("上按钮图片"), Category("PPSkin.NumericUpDown")]
        public Bitmap ButtonPicUP
        {
            get
            {
                return buttonPicUp;
            }
            set
            {
                if (value != null)
                {
                    buttonPicUp = value;
                    pictureBox1.Image = buttonPicUp;
                }
            }
        }

        [Description("上按钮Hover图片"), Category("PPSkin.NumericUpDown")]
        public Bitmap ButtonPicUPHover
        {
            get
            {
                return buttonPicUpHover;
            }
            set
            {
                if (value != null)
                {
                    buttonPicUpHover = value;
                }
            }
        }

        [Description("下按钮图片"), Category("PPSkin.NumericUpDown")]
        public Bitmap ButtonPicDown
        {
            get
            {
                return buttonPicDown;
            }
            set
            {
                if (value != null)
                {
                    buttonPicDown = value;
                    pictureBox2.Image = buttonPicDown;
                }
            }
        }

        [Description("下按钮Hover图片"), Category("PPSkin.NumericUpDown")]
        public Bitmap ButtonPicDownHover
        {
            get
            {
                return buttonPicDownHover;
            }
            set
            {
                if (value != null)
                {
                    buttonPicDownHover = value;
                }
            }
        }

        public PPNumericUpDown()
        {
            InitializeComponent();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.UpdateStyles();
            this.RadiusChanged += PPNumericUpDown_RadiusChanged;

            this.BorderStyle = BorderStyle.None;
            textBox1.Width = this.Width - this.Height - 20;
            textBox1.Location = new Point(this.Height / 2 + 2, 5);
            pictureBox1.Size = new Size(13, 13);
            pictureBox2.Size = new Size(13, 13);
        }

        /// <summary>
        /// 重写CreateParams方法 解决控件过多加载闪烁问题(会导致视频无法播放)
        /// </summary>
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000;//用双缓冲绘制窗口的所有子控件
                return cp;
            }
        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            if (this.Width <= this.Radius + buttonSize.Width + 4)
            {
                this.Width = this.Radius + buttonSize.Width + 5;
            }

            if (this.Height <= buttonSize.Height * 2)
            {
                this.Height = buttonSize.Height * 2;
            }

            if (this.Height <= textBox1.Height + 2)
            {
                this.Height = textBox1.Height + 2;
            }

            textBox1.Width = this.Width - Radius - buttonSize.Width - 4;
            textBox1.Location = new Point(this.Radius / 2 + 2, (this.Height - textBox1.Height) / 2);

            pictureBox1.Location = new Point(base.Width - buttonSize.Width - Radius / 2, 0 + (this.Height / 2 - buttonSize.Height) / 2);
            pictureBox2.Location = new Point(base.Width - buttonSize.Width - Radius / 2, this.Height / 2 + (this.Height / 2 - buttonSize.Height) / 2);
        }

        protected override void OnBackColorChanged(EventArgs e)
        {
            textBox1.BackColor = this.BackColor;
            this.Invalidate();
            base.OnBackColorChanged(e);
        }

        protected override void OnFontChanged(EventArgs e)
        {
            this.textBox1.Font = base.Font;
            this.Invalidate();
            base.OnFontChanged(e);
        }

        protected override void OnForeColorChanged(EventArgs e)
        {
            textBox1.ForeColor = base.ForeColor;
            this.Invalidate();
            base.OnForeColorChanged(e);
        }

        private void PPNumericUpDown_RadiusChanged(object sender, EventArgs e)
        {
            if (this.Width <= this.Radius + buttonSize.Width + 4)
            {
                this.Width = this.Radius + buttonSize.Width + 5;
            }

            if (this.Height <= buttonSize.Height * 2)
            {
                this.Height = buttonSize.Height * 2;
            }

            if (this.Height <= textBox1.Height + 2)
            {
                this.Height = textBox1.Height + 2;
            }

            textBox1.Width = this.Width - Radius - buttonSize.Width - 4;
            textBox1.Location = new Point(this.Radius / 2 + 2, (this.Height - textBox1.Height) / 2);

            pictureBox1.Location = new Point(base.Width - buttonSize.Width - Radius / 2, 0 + (this.Height / 2 - buttonSize.Height) / 2);
            pictureBox2.Location = new Point(base.Width - buttonSize.Width - Radius / 2, this.Height / 2 + (this.Height / 2 - buttonSize.Height) / 2);
        }

        private void textBox1_SizeChanged(object sender, EventArgs e)
        {
            if (this.Width <= this.Radius + buttonSize.Width + 4)
            {
                this.Width = this.Radius + buttonSize.Width + 5;
            }

            if (this.Height <= buttonSize.Height * 2)
            {
                this.Height = buttonSize.Height * 2;
            }

            if (this.Height <= textBox1.Height + 2)
            {
                this.Height = textBox1.Height + 2;
            }

            textBox1.Width = this.Width - Radius - buttonSize.Width - 4;
            textBox1.Location = new Point(this.Radius / 2 + 2, (this.Height - textBox1.Height) / 2);

            pictureBox1.Location = new Point(base.Width - buttonSize.Width - Radius / 2, 0 + (this.Height / 2 - buttonSize.Height) / 2);
            pictureBox2.Location = new Point(base.Width - buttonSize.Width - Radius / 2, this.Height / 2 + (this.Height / 2 - buttonSize.Height) / 2);
        }

        public void Clear()
        {
            textBox1.Clear();
        }

        [Browsable(true)]
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
                int num = Convert.ToInt32(textBox1.Text);
                if (num >= mininum && num <= maxinum)
                {
                    Value = num;
                }
                else if (num > maxinum)
                {
                    Value = maxinum;
                }
                else if (num < mininum)
                {
                    Value = mininum;
                }
            }
            catch
            {
            }
        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = (e.KeyChar < '0' || e.KeyChar > '9') && e.KeyChar != (char)8;  //允许输入数字
        }

        private void pictureBox1_MouseEnter(object sender, EventArgs e)
        {
            pictureBox1.Image = buttonPicUpHover;
        }

        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            pictureBox1.Image = buttonPicUp;
        }

        private void pictureBox2_MouseEnter(object sender, EventArgs e)
        {
            pictureBox2.Image = buttonPicDownHover;
        }

        private void pictureBox2_MouseLeave(object sender, EventArgs e)
        {
            pictureBox2.Image = buttonPicDown;
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            Value += 1;
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            Value -= 1;
        }

        private void PPNumericUpDown_BaseColorChanged(object sender, EventArgs e)
        {
            textBox1.BackColor = this.BaseColor;
        }
    }
}